Micron Document
🎖️GitЯра🎖️

Node / meshtastic / Meshtastic-Android / files / core / testing / src / commonTest / kotlin / org / meshtastic / core / testing / RepositoryFakesTest.kt

Displaying Raw • Download

core/testing/src/commonTest/kotlin/org/meshtastic/core/testing/RepositoryFakesTest.kt 41414f832f938b655c97bc07509bc140ea16e2a3 (41414f83) Text, 23.88 KB

T8b949e/*
* Copyright (c) 2026 Meshtastic LLC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
Tff7b72package T7ee787org.meshtastic.core.testing

Tff7b72import T7ee787app.cash.turbine.test
Tff7b72import T7ee787kotlinx.coroutines.CompletableDeferred
Tff7b72import T7ee787kotlinx.coroutines.async
Tff7b72import T7ee787kotlinx.coroutines.flow.first
Tff7b72import T7ee787kotlinx.coroutines.test.runTest
Tff7b72import T7ee787org.meshtastic.core.database.entity.FirmwareRelease
Tff7b72import T7ee787org.meshtastic.core.database.entity.QuickChatAction
Tff7b72import T7ee787org.meshtastic.core.model.ConnectionEpochs
Tff7b72import T7ee787org.meshtastic.core.model.ConnectionState
Tff7b72import T7ee787org.meshtastic.core.model.DataPacket
Tff7b72import T7ee787org.meshtastic.core.model.DeviceHardware
Tff7b72import T7ee787org.meshtastic.core.model.MessageStatus
Tff7b72import T7ee787org.meshtastic.core.repository.EditSettingsTransactionException
Tff7b72import T7ee787org.meshtastic.core.repository.LocalNodeUnavailableException
Tff7b72import T7ee787org.meshtastic.core.repository.PacketQueueRejectedException
Tff7b72import T7ee787org.meshtastic.proto.AdminMessage
Tff7b72import T7ee787org.meshtastic.proto.Channel
Tff7b72import T7ee787org.meshtastic.proto.ChannelSettings
Tff7b72import T7ee787org.meshtastic.proto.Config
Tff7b72import T7ee787org.meshtastic.proto.ModuleConfig
Tff7b72import T7ee787org.meshtastic.proto.PortNum
Tff7b72import T7ee787org.meshtastic.proto.Position
Tff7b72import T7ee787org.meshtastic.proto.User
Tff7b72import T7ee787kotlin.test.Test
Tff7b72import T7ee787kotlin.test.assertContentEquals
Tff7b72import T7ee787kotlin.test.assertEquals
Tff7b72import T7ee787kotlin.test.assertFailsWith
Tff7b72import T7ee787kotlin.test.assertFalse
Tff7b72import T7ee787kotlin.test.assertIs
Tff7b72import T7ee787kotlin.test.assertNotSame
Tff7b72import T7ee787kotlin.test.assertNull
Tff7b72import T7ee787kotlin.test.assertSame
Tff7b72import T7ee787kotlin.test.assertTrue
Tff7b72import T7ee787org.meshtastic.core.model.Position Tff7b72as Te6edf3ModelPosition

Tff7b72class T56d364RepositoryFakesTest Tb4b4b4{

Tf0883e@Test
Tff7b72fun Td2a8ff`FakeDeviceHardwareRepository returns seeded hardware and records calls`Tb4b4b4(Tb4b4b4) Tff7b72= Te6edf3runTest Tb4b4b4{
Tff7b72val Te6edf3repo Tff7b72= Te6edf3FakeDeviceHardwareRepositoryTb4b4b4(Tb4b4b4)
Tff7b72val Te6edf3hw Tff7b72= Te6edf3DeviceHardwareTb4b4b4(Te6edf3hwModel Tff7b72= T79c0ff4T79c0ff2Tb4b4b4, Te6edf3hwModelSlug Tff7b72= Ta5d6ff"Ta5d6ffTESTTa5d6ff"Tb4b4b4, Te6edf3platformioTarget Tff7b72= Ta5d6ff"Ta5d6fftloraTa5d6ff"Tb4b4b4)
Te6edf3repoTb4b4b4.Te6edf3setHardwareTb4b4b4(Te6edf3hwModel Tff7b72= T79c0ff4T79c0ff2Tb4b4b4, Te6edf3target Tff7b72= Ta5d6ff"Ta5d6fftloraTa5d6ff"Tb4b4b4, Te6edf3device Tff7b72= Te6edf3hwTb4b4b4)

Tff7b72val Te6edf3hit Tff7b72= Te6edf3repoTb4b4b4.Te6edf3getDeviceHardwareByModelTb4b4b4(Te6edf3hwModel Tff7b72= T79c0ff4T79c0ff2Tb4b4b4, Te6edf3target Tff7b72= Ta5d6ff"Ta5d6fftloraTa5d6ff"Tb4b4b4, Te6edf3forceRefresh Tff7b72= Tff7b72falseTb4b4b4)
Tff7b72val Te6edf3miss Tff7b72= Te6edf3repoTb4b4b4.Te6edf3getDeviceHardwareByModelTb4b4b4(Te6edf3hwModel Tff7b72= T79c0ff9T79c0ff9Tb4b4b4)

Te6edf3assertEqualsTb4b4b4(Te6edf3hwTb4b4b4, Te6edf3hitTb4b4b4.Te6edf3getOrNullTb4b4b4(Tb4b4b4)Tb4b4b4)
Te6edf3assertNullTb4b4b4(Te6edf3missTb4b4b4.Te6edf3getOrNullTb4b4b4(Tb4b4b4)Tb4b4b4)
Te6edf3assertEqualsTb4b4b4(T79c0ff2Tb4b4b4, Te6edf3repoTb4b4b4.Te6edf3recordedCallsTb4b4b4.Te6edf3sizeTb4b4b4)
Te6edf3assertEqualsTb4b4b4(Te6edf3TripleTb4b4b4(T79c0ff4T79c0ff2Tb4b4b4, Ta5d6ff"Ta5d6fftloraTa5d6ff"Tb4b4b4, Tff7b72falseTb4b4b4)Tb4b4b4, Te6edf3repoTb4b4b4.Te6edf3recordedCallsTb4b4b4.Te6edf3firstTb4b4b4(Tb4b4b4)Tb4b4b4)
Tb4b4b4}

Tf0883e@Test
Tff7b72fun Td2a8ff`FakeFirmwareReleaseRepository emits stable and alpha releases`Tb4b4b4(Tb4b4b4) Tff7b72= Te6edf3runTest Tb4b4b4{
Tff7b72val Te6edf3repo Tff7b72= Te6edf3FakeFirmwareReleaseRepositoryTb4b4b4(Tb4b4b4)
Tff7b72val Te6edf3stable Tff7b72= Te6edf3FirmwareReleaseTb4b4b4(Te6edf3id Tff7b72= Ta5d6ff"Ta5d6ff1.0Ta5d6ff"Tb4b4b4, Te6edf3title Tff7b72= Ta5d6ff"Ta5d6ff1.0Ta5d6ff"Tb4b4b4, Te6edf3pageUrl Tff7b72= Ta5d6ff"Ta5d6ff"Tb4b4b4, Te6edf3zipUrl Tff7b72= Ta5d6ff"Ta5d6ff"Tb4b4b4)
Tff7b72val Te6edf3alpha Tff7b72= Te6edf3FirmwareReleaseTb4b4b4(Te6edf3id Tff7b72= Ta5d6ff"Ta5d6ff1.1-aTa5d6ff"Tb4b4b4, Te6edf3title Tff7b72= Ta5d6ff"Ta5d6ff1.1-aTa5d6ff"Tb4b4b4, Te6edf3pageUrl Tff7b72= Ta5d6ff"Ta5d6ff"Tb4b4b4, Te6edf3zipUrl Tff7b72= Ta5d6ff"Ta5d6ff"Tb4b4b4)

Te6edf3repoTb4b4b4.Te6edf3setStableReleaseTb4b4b4(Te6edf3stableTb4b4b4)
Te6edf3repoTb4b4b4.Te6edf3setAlphaReleaseTb4b4b4(Te6edf3alphaTb4b4b4)

Te6edf3assertEqualsTb4b4b4(Te6edf3stableTb4b4b4, Te6edf3repoTb4b4b4.Te6edf3stableReleaseTb4b4b4.Te6edf3firstTb4b4b4(Tb4b4b4)Tb4b4b4)
Te6edf3assertEqualsTb4b4b4(Te6edf3alphaTb4b4b4, Te6edf3repoTb4b4b4.Te6edf3alphaReleaseTb4b4b4.Te6edf3firstTb4b4b4(Tb4b4b4)Tb4b4b4)

Te6edf3repoTb4b4b4.Te6edf3invalidateCacheTb4b4b4(Tb4b4b4)
Te6edf3repoTb4b4b4.Te6edf3invalidateCacheTb4b4b4(Tb4b4b4)
Te6edf3assertEqualsTb4b4b4(T79c0ff2Tb4b4b4, Te6edf3repoTb4b4b4.Te6edf3invalidateCacheCallsTb4b4b4)
Tb4b4b4}

Tf0883e@Test
Tff7b72fun Td2a8ff`FakeQuickChatActionRepository upsert delete and reorder`Tb4b4b4(Tb4b4b4) Tff7b72= Te6edf3runTest Tb4b4b4{
Tff7b72val Te6edf3repo Tff7b72= Te6edf3FakeQuickChatActionRepositoryTb4b4b4(Tb4b4b4)
Tff7b72val Te6edf3a Tff7b72= Te6edf3QuickChatActionTb4b4b4(Te6edf3uuid Tff7b72= T79c0ff1LTb4b4b4, Te6edf3name Tff7b72= Ta5d6ff"Ta5d6ffATa5d6ff"Tb4b4b4, Te6edf3message Tff7b72= Ta5d6ff"Ta5d6ffhiTa5d6ff"Tb4b4b4, Te6edf3position Tff7b72= T79c0ff0Tb4b4b4)
Tff7b72val Te6edf3b Tff7b72= Te6edf3QuickChatActionTb4b4b4(Te6edf3uuid Tff7b72= T79c0ff2LTb4b4b4, Te6edf3name Tff7b72= Ta5d6ff"Ta5d6ffBTa5d6ff"Tb4b4b4, Te6edf3message Tff7b72= Ta5d6ff"Ta5d6ffbyeTa5d6ff"Tb4b4b4, Te6edf3position Tff7b72= T79c0ff1Tb4b4b4)

Te6edf3repoTb4b4b4.Te6edf3upsertTb4b4b4(Te6edf3aTb4b4b4)
Te6edf3repoTb4b4b4.Te6edf3upsertTb4b4b4(Te6edf3bTb4b4b4)
Te6edf3assertEqualsTb4b4b4(Te6edf3listOfTb4b4b4(Te6edf3aTb4b4b4, Te6edf3bTb4b4b4)Tb4b4b4, Te6edf3repoTb4b4b4.Te6edf3getAllActionsTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3firstTb4b4b4(Tb4b4b4)Tb4b4b4)

Te6edf3repoTb4b4b4.Te6edf3setItemPositionTb4b4b4(Te6edf3uuid Tff7b72= T79c0ff1LTb4b4b4, Te6edf3newPos Tff7b72= T79c0ff5Tb4b4b4)
Te6edf3assertEqualsTb4b4b4(Te6edf3listOfTb4b4b4(T79c0ff2LTb4b4b4, T79c0ff1LTb4b4b4)Tb4b4b4, Te6edf3repoTb4b4b4.Te6edf3getAllActionsTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3firstTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3map Tb4b4b4{ Tffa657itTb4b4b4.Te6edf3uuid Tb4b4b4}Tb4b4b4)

Te6edf3repoTb4b4b4.Te6edf3deleteTb4b4b4(Te6edf3bTb4b4b4)
Te6edf3assertEqualsTb4b4b4(T79c0ff1Tb4b4b4, Te6edf3repoTb4b4b4.Te6edf3currentActionsTb4b4b4.Te6edf3sizeTb4b4b4)

Te6edf3repoTb4b4b4.Te6edf3deleteAllTb4b4b4(Tb4b4b4)
Te6edf3assertTrueTb4b4b4(Te6edf3repoTb4b4b4.Te6edf3currentActionsTb4b4b4.Te6edf3isEmptyTb4b4b4(Tb4b4b4)Tb4b4b4)
Tb4b4b4}

Tf0883e@Test
Tff7b72fun Td2a8ff`FakeQuickChatActionRepository delete compacts positions`Tb4b4b4(Tb4b4b4) Tff7b72= Te6edf3runTest Tb4b4b4{
Tff7b72val Te6edf3repo Tff7b72= Te6edf3FakeQuickChatActionRepositoryTb4b4b4(Tb4b4b4)
Tff7b72val Te6edf3a Tff7b72= Te6edf3QuickChatActionTb4b4b4(Te6edf3uuid Tff7b72= T79c0ff1LTb4b4b4, Te6edf3name Tff7b72= Ta5d6ff"Ta5d6ffATa5d6ff"Tb4b4b4, Te6edf3message Tff7b72= Ta5d6ff"Ta5d6ff"Tb4b4b4, Te6edf3position Tff7b72= T79c0ff0Tb4b4b4)
Tff7b72val Te6edf3b Tff7b72= Te6edf3QuickChatActionTb4b4b4(Te6edf3uuid Tff7b72= T79c0ff2LTb4b4b4, Te6edf3name Tff7b72= Ta5d6ff"Ta5d6ffBTa5d6ff"Tb4b4b4, Te6edf3message Tff7b72= Ta5d6ff"Ta5d6ff"Tb4b4b4, Te6edf3position Tff7b72= T79c0ff1Tb4b4b4)
Tff7b72val Te6edf3c Tff7b72= Te6edf3QuickChatActionTb4b4b4(Te6edf3uuid Tff7b72= T79c0ff3LTb4b4b4, Te6edf3name Tff7b72= Ta5d6ff"Ta5d6ffCTa5d6ff"Tb4b4b4, Te6edf3message Tff7b72= Ta5d6ff"Ta5d6ff"Tb4b4b4, Te6edf3position Tff7b72= T79c0ff2Tb4b4b4)
Te6edf3repoTb4b4b4.Te6edf3upsertTb4b4b4(Te6edf3aTb4b4b4)
Te6edf3repoTb4b4b4.Te6edf3upsertTb4b4b4(Te6edf3bTb4b4b4)
Te6edf3repoTb4b4b4.Te6edf3upsertTb4b4b4(Te6edf3cTb4b4b4)

Te6edf3repoTb4b4b4.Te6edf3deleteTb4b4b4(Te6edf3bTb4b4b4)

T8b949e// Matches real DAO's decrementPositionsAfter: positions must stay contiguous.
Te6edf3assertEqualsTb4b4b4(Te6edf3listOfTb4b4b4(T79c0ff1L Te6edf3to T79c0ff0Tb4b4b4, T79c0ff3L Te6edf3to T79c0ff1Tb4b4b4)Tb4b4b4, Te6edf3repoTb4b4b4.Te6edf3currentActionsTb4b4b4.Te6edf3map Tb4b4b4{ Tffa657itTb4b4b4.Te6edf3uuid Te6edf3to Tffa657itTb4b4b4.Te6edf3position Tb4b4b4}Tb4b4b4)
Tb4b4b4}

Tf0883e@Test
Tff7b72fun Td2a8ff`FakeTracerouteSnapshotRepository roundtrips positions keyed by log uuid`Tb4b4b4(Tb4b4b4) Tff7b72= Te6edf3runTest Tb4b4b4{
Tff7b72val Te6edf3repo Tff7b72= Te6edf3FakeTracerouteSnapshotRepositoryTb4b4b4(Tb4b4b4)
Tff7b72val Te6edf3positions Tff7b72= Te6edf3mapOfTb4b4b4(T79c0ff1 Te6edf3to Te6edf3PositionTb4b4b4(Te6edf3latitude_i Tff7b72= T79c0ff1T79c0ff0Tb4b4b4)Tb4b4b4, T79c0ff2 Te6edf3to Te6edf3PositionTb4b4b4(Te6edf3latitude_i Tff7b72= T79c0ff2T79c0ff0Tb4b4b4)Tb4b4b4)
Te6edf3repoTb4b4b4.Te6edf3upsertSnapshotPositionsTb4b4b4(Te6edf3logUuid Tff7b72= Ta5d6ff"Ta5d6fflog-1Ta5d6ff"Tb4b4b4, Te6edf3requestId Tff7b72= T79c0ff9T79c0ff9Tb4b4b4, Te6edf3positions Tff7b72= Te6edf3positionsTb4b4b4)

Te6edf3repoTb4b4b4.Te6edf3getSnapshotPositionsTb4b4b4(Ta5d6ff"Ta5d6fflog-1Ta5d6ff"Tb4b4b4)Tb4b4b4.Te6edf3test Tb4b4b4{ Te6edf3assertEqualsTb4b4b4(Te6edf3positionsTb4b4b4, Te6edf3awaitItemTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4}
Te6edf3assertEqualsTb4b4b4(T79c0ff9T79c0ff9Tb4b4b4, Te6edf3repoTb4b4b4.Te6edf3lastRequestIdTb4b4b4(Ta5d6ff"Ta5d6fflog-1Ta5d6ff"Tb4b4b4)Tb4b4b4)
Te6edf3assertNullTb4b4b4(Te6edf3repoTb4b4b4.Te6edf3lastRequestIdTb4b4b4(Ta5d6ff"Ta5d6ffotherTa5d6ff"Tb4b4b4)Tb4b4b4)
Tb4b4b4}

Tf0883e@Test
Tff7b72fun Td2a8ff`FakeDatabaseManager associates only the active address`Tb4b4b4(Tb4b4b4) Tff7b72= Te6edf3runTest Tb4b4b4{
Tff7b72val Te6edf3manager Tff7b72= Te6edf3FakeDatabaseManagerTb4b4b4(Tb4b4b4)
Te6edf3managerTb4b4b4.Te6edf3switchActiveDatabaseTb4b4b4(Ta5d6ff"Ta5d6ffactiveTa5d6ff"Tb4b4b4)

Te6edf3managerTb4b4b4.Te6edf3associateDeviceTb4b4b4(Te6edf3address Tff7b72= Ta5d6ff"Ta5d6ffstaleTa5d6ff"Tb4b4b4, Te6edf3nodeNum Tff7b72= T79c0ff1Tb4b4b4, Te6edf3deviceId Tff7b72= Ta5d6ff"Ta5d6ffoldTa5d6ff"Tb4b4b4, Te6edf3isSessionActive Tff7b72= Tb4b4b4{ Tff7b72true Tb4b4b4}Tb4b4b4)
Te6edf3assertNullTb4b4b4(Te6edf3managerTb4b4b4.Te6edf3lastAssociatedAddressTb4b4b4)
Te6edf3assertNullTb4b4b4(Te6edf3managerTb4b4b4.Te6edf3lastAssociatedNodeTb4b4b4)
Te6edf3assertNullTb4b4b4(Te6edf3managerTb4b4b4.Te6edf3lastAssociatedDeviceIdTb4b4b4)

Te6edf3managerTb4b4b4.Te6edf3associateDeviceTb4b4b4(Te6edf3address Tff7b72= Ta5d6ff"Ta5d6ffactiveTa5d6ff"Tb4b4b4, Te6edf3nodeNum Tff7b72= T79c0ff2Tb4b4b4, Te6edf3deviceId Tff7b72= Ta5d6ff"Ta5d6ffinactiveTa5d6ff"Tb4b4b4, Te6edf3isSessionActive Tff7b72= Tb4b4b4{ Tff7b72false Tb4b4b4}Tb4b4b4)
Te6edf3assertNullTb4b4b4(Te6edf3managerTb4b4b4.Te6edf3lastAssociatedAddressTb4b4b4)
Te6edf3assertNullTb4b4b4(Te6edf3managerTb4b4b4.Te6edf3lastAssociatedNodeTb4b4b4)
Te6edf3assertNullTb4b4b4(Te6edf3managerTb4b4b4.Te6edf3lastAssociatedDeviceIdTb4b4b4)

Te6edf3managerTb4b4b4.Te6edf3associateDeviceTb4b4b4(Te6edf3address Tff7b72= Ta5d6ff"Ta5d6ffactiveTa5d6ff"Tb4b4b4, Te6edf3nodeNum Tff7b72= T79c0ff3Tb4b4b4, Te6edf3deviceId Tff7b72= Ta5d6ff"Ta5d6fffreshTa5d6ff"Tb4b4b4, Te6edf3isSessionActive Tff7b72= Tb4b4b4{ Tff7b72true Tb4b4b4}Tb4b4b4)
Te6edf3assertEqualsTb4b4b4(Ta5d6ff"Ta5d6ffactiveTa5d6ff"Tb4b4b4, Te6edf3managerTb4b4b4.Te6edf3lastAssociatedAddressTb4b4b4)
Te6edf3assertEqualsTb4b4b4(T79c0ff3Tb4b4b4, Te6edf3managerTb4b4b4.Te6edf3lastAssociatedNodeTb4b4b4)
Te6edf3assertEqualsTb4b4b4(Ta5d6ff"Ta5d6fffreshTa5d6ff"Tb4b4b4, Te6edf3managerTb4b4b4.Te6edf3lastAssociatedDeviceIdTb4b4b4)
Tb4b4b4}

Tf0883e@Test
Tff7b72fun Td2a8ff`service repository fake preserves connection epoch semantics`Tb4b4b4(Tb4b4b4) Tb4b4b4{
Tff7b72val Te6edf3repository Tff7b72= Te6edf3FakeServiceRepositoryTb4b4b4(Tb4b4b4)

Te6edf3repositoryTb4b4b4.Te6edf3setConnectionStateTb4b4b4(Te6edf3ConnectionStateTb4b4b4.Te6edf3ConnectedTb4b4b4)
Te6edf3assertEqualsTb4b4b4(Te6edf3ConnectionEpochsTb4b4b4(Te6edf3completedHandshakes Tff7b72= T79c0ff1Tb4b4b4)Tb4b4b4, Te6edf3repositoryTb4b4b4.Te6edf3connectionEpochsTb4b4b4.Te6edf3valueTb4b4b4)

Te6edf3repositoryTb4b4b4.Te6edf3setConnectionStateTb4b4b4(Te6edf3ConnectionStateTb4b4b4.Te6edf3ConnectedTb4b4b4)
Te6edf3assertEqualsTb4b4b4(Te6edf3ConnectionEpochsTb4b4b4(Te6edf3completedHandshakes Tff7b72= T79c0ff1Tb4b4b4)Tb4b4b4, Te6edf3repositoryTb4b4b4.Te6edf3connectionEpochsTb4b4b4.Te6edf3valueTb4b4b4)

Te6edf3repositoryTb4b4b4.Te6edf3setConnectionStateTb4b4b4(Te6edf3ConnectionStateTb4b4b4.Te6edf3ConnectingTb4b4b4)
Te6edf3assertEqualsTb4b4b4(
Te6edf3ConnectionEpochsTb4b4b4(
Te6edf3departures Tff7b72= T79c0ff1Tb4b4b4,
Te6edf3completedHandshakes Tff7b72= T79c0ff1Tb4b4b4,
Te6edf3handshakesAtLastDeparture Tff7b72= T79c0ff1Tb4b4b4,
Te6edf3lastDepartureState Tff7b72= Te6edf3ConnectionStateTb4b4b4.Te6edf3ConnectingTb4b4b4,
Tb4b4b4)Tb4b4b4,
Te6edf3repositoryTb4b4b4.Te6edf3connectionEpochsTb4b4b4.Te6edf3valueTb4b4b4,
Tb4b4b4)

Te6edf3repositoryTb4b4b4.Te6edf3setConnectionStateTb4b4b4(Te6edf3ConnectionStateTb4b4b4.Te6edf3ConnectedTb4b4b4)
Te6edf3assertEqualsTb4b4b4(
Te6edf3ConnectionEpochsTb4b4b4(
Te6edf3departures Tff7b72= T79c0ff1Tb4b4b4,
Te6edf3completedHandshakes Tff7b72= T79c0ff2Tb4b4b4,
Te6edf3handshakesAtLastDeparture Tff7b72= T79c0ff1Tb4b4b4,
Te6edf3lastDepartureState Tff7b72= Te6edf3ConnectionStateTb4b4b4.Te6edf3ConnectingTb4b4b4,
Tb4b4b4)Tb4b4b4,
Te6edf3repositoryTb4b4b4.Te6edf3connectionEpochsTb4b4b4.Te6edf3valueTb4b4b4,
Tb4b4b4)
Tb4b4b4}

Tf0883e@Test
Tff7b72fun Td2a8ff`FakeRadioController preserves configuration and fixed-position evidence until reset`Tb4b4b4(Tb4b4b4) Tff7b72= Te6edf3runTest Tb4b4b4{
Tff7b72val Te6edf3controller Tff7b72= Te6edf3FakeRadioControllerTb4b4b4(Tb4b4b4)
Tff7b72val Te6edf3local Tff7b72= Te6edf3ConfigTb4b4b4(Te6edf3device Tff7b72= Te6edf3ConfigTb4b4b4.Te6edf3DeviceConfigTb4b4b4(Tb4b4b4)Tb4b4b4)
Tff7b72val Te6edf3admin Tff7b72= Te6edf3ConfigTb4b4b4(Te6edf3lora Tff7b72= Te6edf3ConfigTb4b4b4.Te6edf3LoRaConfigTb4b4b4(Te6edf3hop_limit Tff7b72= T79c0ff5Tb4b4b4)Tb4b4b4)
Tff7b72val Te6edf3module Tff7b72= Te6edf3ModuleConfigTb4b4b4(Te6edf3serial Tff7b72= Te6edf3ModuleConfigTb4b4b4.Te6edf3SerialConfigTb4b4b4(Te6edf3enabled Tff7b72= Tff7b72trueTb4b4b4)Tb4b4b4)
Tff7b72val Te6edf3position Tff7b72= Te6edf3ModelPositionTb4b4b4(Te6edf3latitude Tff7b72= T79c0ff1.0Tb4b4b4, Te6edf3longitude Tff7b72= T79c0ff2.0Tb4b4b4, Te6edf3altitude Tff7b72= T79c0ff3Tb4b4b4)

Te6edf3controllerTb4b4b4.Te6edf3setLocalConfigTb4b4b4(Te6edf3localTb4b4b4)
Te6edf3controllerTb4b4b4.Te6edf3setConfigTb4b4b4(Te6edf3destNum Tff7b72= T79c0ff7Tb4b4b4, Te6edf3config Tff7b72= Te6edf3adminTb4b4b4, Te6edf3packetId Tff7b72= T79c0ff8Tb4b4b4)
Te6edf3controllerTb4b4b4.Te6edf3setModuleConfigTb4b4b4(Te6edf3destNum Tff7b72= T79c0ff7Tb4b4b4, Te6edf3config Tff7b72= Te6edf3moduleTb4b4b4, Te6edf3packetId Tff7b72= T79c0ff9Tb4b4b4)
Te6edf3controllerTb4b4b4.Te6edf3setFixedPositionTb4b4b4(Te6edf3destNum Tff7b72= T79c0ff7Tb4b4b4, Te6edf3position Tff7b72= Te6edf3positionTb4b4b4)
Te6edf3controllerTb4b4b4.Te6edf3setConnectionStateTb4b4b4(Te6edf3ConnectionStateTb4b4b4.Te6edf3ConnectedTb4b4b4)

Te6edf3assertEqualsTb4b4b4(
Te6edf3listOfTb4b4b4(
Te6edf3FakeRadioControllerTb4b4b4.Te6edf3ConfigWriteTb4b4b4(Te6edf3destination Tff7b72= Tff7b72nullTb4b4b4, Te6edf3config Tff7b72= Te6edf3localTb4b4b4)Tb4b4b4,
Te6edf3FakeRadioControllerTb4b4b4.Te6edf3ConfigWriteTb4b4b4(Te6edf3destination Tff7b72= T79c0ff7Tb4b4b4, Te6edf3config Tff7b72= Te6edf3adminTb4b4b4)Tb4b4b4,
Tb4b4b4)Tb4b4b4,
Te6edf3controllerTb4b4b4.Te6edf3configWritesTb4b4b4,
Tb4b4b4)
Te6edf3assertEqualsTb4b4b4(Te6edf3listOfTb4b4b4(Te6edf3localTb4b4b4)Tb4b4b4, Te6edf3controllerTb4b4b4.Te6edf3localConfigsTb4b4b4)
Te6edf3assertEqualsTb4b4b4(Te6edf3localTb4b4b4, Te6edf3controllerTb4b4b4.Te6edf3lastLocalConfigTb4b4b4)
Te6edf3assertEqualsTb4b4b4(
Te6edf3listOfTb4b4b4(Te6edf3FakeRadioControllerTb4b4b4.Te6edf3ModuleConfigWriteTb4b4b4(Te6edf3destination Tff7b72= T79c0ff7Tb4b4b4, Te6edf3config Tff7b72= Te6edf3moduleTb4b4b4)Tb4b4b4)Tb4b4b4,
Te6edf3controllerTb4b4b4.Te6edf3moduleConfigWritesTb4b4b4,
Tb4b4b4)
Te6edf3assertEqualsTb4b4b4(Te6edf3listOfTb4b4b4(Te6edf3moduleTb4b4b4)Tb4b4b4, Te6edf3controllerTb4b4b4.Te6edf3allModuleConfigsTb4b4b4)
Te6edf3assertEqualsTb4b4b4(Te6edf3listOfTb4b4b4(T79c0ff7Tb4b4b4)Tb4b4b4, Te6edf3controllerTb4b4b4.Te6edf3moduleConfigDestinationsTb4b4b4)
Te6edf3assertEqualsTb4b4b4(Te6edf3listOfTb4b4b4(Te6edf3positionTb4b4b4)Tb4b4b4, Te6edf3controllerTb4b4b4.Te6edf3fixedPositionsTb4b4b4)
Te6edf3assertEqualsTb4b4b4(Te6edf3ConnectionStateTb4b4b4.Te6edf3ConnectedTb4b4b4, Te6edf3controllerTb4b4b4.Te6edf3connectionStateTb4b4b4.Te6edf3valueTb4b4b4)
Te6edf3assertEqualsTb4b4b4(Te6edf3ConnectionEpochsTb4b4b4(Te6edf3completedHandshakes Tff7b72= T79c0ff1Tb4b4b4)Tb4b4b4, Te6edf3controllerTb4b4b4.Te6edf3connectionEpochsTb4b4b4.Te6edf3valueTb4b4b4)

Te6edf3controllerTb4b4b4.Te6edf3resetTb4b4b4(Tb4b4b4)

Te6edf3assertTrueTb4b4b4(Te6edf3controllerTb4b4b4.Te6edf3configWritesTb4b4b4.Te6edf3isEmptyTb4b4b4(Tb4b4b4)Tb4b4b4)
Te6edf3assertTrueTb4b4b4(Te6edf3controllerTb4b4b4.Te6edf3localConfigsTb4b4b4.Te6edf3isEmptyTb4b4b4(Tb4b4b4)Tb4b4b4)
Te6edf3assertTrueTb4b4b4(Te6edf3controllerTb4b4b4.Te6edf3moduleConfigWritesTb4b4b4.Te6edf3isEmptyTb4b4b4(Tb4b4b4)Tb4b4b4)
Te6edf3assertTrueTb4b4b4(Te6edf3controllerTb4b4b4.Te6edf3allModuleConfigsTb4b4b4.Te6edf3isEmptyTb4b4b4(Tb4b4b4)Tb4b4b4)
Te6edf3assertTrueTb4b4b4(Te6edf3controllerTb4b4b4.Te6edf3moduleConfigDestinationsTb4b4b4.Te6edf3isEmptyTb4b4b4(Tb4b4b4)Tb4b4b4)
Te6edf3assertTrueTb4b4b4(Te6edf3controllerTb4b4b4.Te6edf3fixedPositionsTb4b4b4.Te6edf3isEmptyTb4b4b4(Tb4b4b4)Tb4b4b4)
Te6edf3assertEqualsTb4b4b4(Te6edf3ConnectionStateTb4b4b4.Te6edf3DisconnectedTb4b4b4, Te6edf3controllerTb4b4b4.Te6edf3connectionStateTb4b4b4.Te6edf3valueTb4b4b4)
Te6edf3assertEqualsTb4b4b4(
Te6edf3ConnectionEpochsTb4b4b4(
Te6edf3departures Tff7b72= T79c0ff1Tb4b4b4,
Te6edf3completedHandshakes Tff7b72= T79c0ff1Tb4b4b4,
Te6edf3handshakesAtLastDeparture Tff7b72= T79c0ff1Tb4b4b4,
Te6edf3lastDepartureState Tff7b72= Te6edf3ConnectionStateTb4b4b4.Te6edf3DisconnectedTb4b4b4,
Tb4b4b4)Tb4b4b4,
Te6edf3controllerTb4b4b4.Te6edf3connectionEpochsTb4b4b4.Te6edf3valueTb4b4b4,
Tb4b4b4)
Tb4b4b4}

Tf0883e@Test
Tff7b72fun Td2a8ff`FakeRadioController uses null destination consistently for local config writes`Tb4b4b4(Tb4b4b4) Tff7b72= Te6edf3runTest Tb4b4b4{
Tff7b72val Te6edf3controller Tff7b72= Te6edf3FakeRadioControllerTb4b4b4(Tb4b4b4)
Tff7b72val Te6edf3config Tff7b72= Te6edf3ConfigTb4b4b4(Te6edf3device Tff7b72= Te6edf3ConfigTb4b4b4.Te6edf3DeviceConfigTb4b4b4(Tb4b4b4)Tb4b4b4)
Tff7b72val Te6edf3moduleConfig Tff7b72= Te6edf3ModuleConfigTb4b4b4(Te6edf3serial Tff7b72= Te6edf3ModuleConfigTb4b4b4.Te6edf3SerialConfigTb4b4b4(Te6edf3enabled Tff7b72= Tff7b72trueTb4b4b4)Tb4b4b4)

Te6edf3controllerTb4b4b4.Te6edf3setConfigTb4b4b4(Te6edf3destNum Tff7b72= T79c0ff0Tb4b4b4, Te6edf3config Tff7b72= Te6edf3configTb4b4b4, Te6edf3packetId Tff7b72= T79c0ff1Tb4b4b4)
Te6edf3controllerTb4b4b4.Te6edf3setModuleConfigTb4b4b4(Te6edf3destNum Tff7b72= T79c0ff0Tb4b4b4, Te6edf3config Tff7b72= Te6edf3moduleConfigTb4b4b4, Te6edf3packetId Tff7b72= T79c0ff2Tb4b4b4)
Te6edf3controllerTb4b4b4.Te6edf3editLocalSettings Tb4b4b4{
Te6edf3setConfigTb4b4b4(Te6edf3configTb4b4b4)
Te6edf3setModuleConfigTb4b4b4(Te6edf3moduleConfigTb4b4b4)
Tb4b4b4}

Te6edf3assertEqualsTb4b4b4(
Te6edf3ListTb4b4b4(T79c0ff2Tb4b4b4) Tb4b4b4{ Te6edf3FakeRadioControllerTb4b4b4.Te6edf3ConfigWriteTb4b4b4(Te6edf3destination Tff7b72= Tff7b72nullTb4b4b4, Te6edf3config Tff7b72= Te6edf3configTb4b4b4) Tb4b4b4}Tb4b4b4,
Te6edf3controllerTb4b4b4.Te6edf3configWritesTb4b4b4,
Tb4b4b4)
Te6edf3assertEqualsTb4b4b4(
Te6edf3ListTb4b4b4(T79c0ff2Tb4b4b4) Tb4b4b4{ Te6edf3FakeRadioControllerTb4b4b4.Te6edf3ModuleConfigWriteTb4b4b4(Te6edf3destination Tff7b72= Tff7b72nullTb4b4b4, Te6edf3config Tff7b72= Te6edf3moduleConfigTb4b4b4) Tb4b4b4}Tb4b4b4,
Te6edf3controllerTb4b4b4.Te6edf3moduleConfigWritesTb4b4b4,
Tb4b4b4)
Te6edf3assertEqualsTb4b4b4(Te6edf3ListTb4b4b4(T79c0ff2Tb4b4b4) Tb4b4b4{ Te6edf3moduleConfig Tb4b4b4}Tb4b4b4, Te6edf3controllerTb4b4b4.Te6edf3localModuleConfigsTb4b4b4)
Te6edf3assertEqualsTb4b4b4(Te6edf3ListTff7b72<Tffa657Int?Tff7b72>Tb4b4b4(T79c0ff2Tb4b4b4) Tb4b4b4{ Tff7b72null Tb4b4b4}Tb4b4b4, Te6edf3controllerTb4b4b4.Te6edf3moduleConfigDestinationsTb4b4b4)
Tb4b4b4}

Tf0883e@Test
Tff7b72fun Td2a8ff`FakeCommandSender mirrors queued status after successful admission`Tb4b4b4(Tb4b4b4) Tff7b72= Te6edf3runTest Tb4b4b4{
Tff7b72val Te6edf3sender Tff7b72= Te6edf3FakeCommandSenderTb4b4b4(Tb4b4b4)
Tff7b72val Te6edf3packet Tff7b72=
Te6edf3DataPacketTb4b4b4(Te6edf3bytes Tff7b72= Tff7b72nullTb4b4b4, Te6edf3dataType Tff7b72= Te6edf3PortNumTb4b4b4.Te6edf3TEXT_MESSAGE_APPTb4b4b4.Te6edf3valueTb4b4b4)Tb4b4b4.Te6edf3apply Tb4b4b4{ Te6edf3errorMessage Tff7b72= Ta5d6ff"Ta5d6fforiginalTa5d6ff" Tb4b4b4}

Te6edf3senderTb4b4b4.Te6edf3sendDataTb4b4b4(Te6edf3packetTb4b4b4)

Te6edf3assertEqualsTb4b4b4(Te6edf3MessageStatusTb4b4b4.Te6edf3QUEUEDTb4b4b4, Te6edf3packetTb4b4b4.Te6edf3statusTb4b4b4)
Te6edf3assertTrueTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3id Tff7b72!Tff7b72= T79c0ff0Tb4b4b4)
Te6edf3assertTrueTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3time Tff7b72> T79c0ff0Tb4b4b4)
Tff7b72val Te6edf3stored Tff7b72= Te6edf3senderTb4b4b4.Te6edf3sentPacketsTb4b4b4.Te6edf3singleTb4b4b4(Tb4b4b4)
Te6edf3assertNotSameTb4b4b4(Te6edf3packetTb4b4b4, Te6edf3storedTb4b4b4)
Te6edf3assertEqualsTb4b4b4(Te6edf3packetTb4b4b4, Te6edf3storedTb4b4b4)
Te6edf3assertEqualsTb4b4b4(Ta5d6ff"Ta5d6fforiginalTa5d6ff"Tb4b4b4, Te6edf3storedTb4b4b4.Te6edf3errorMessageTb4b4b4)

Tff7b72val Te6edf3storedId Tff7b72= Te6edf3storedTb4b4b4.Te6edf3id
Te6edf3packetTb4b4b4.Te6edf3id Tff7b72= Te6edf3storedId Tff7b72+ T79c0ff1
Te6edf3packetTb4b4b4.Te6edf3errorMessage Tff7b72= Ta5d6ff"Ta5d6ffcaller mutationTa5d6ff"
Te6edf3storedTb4b4b4.Te6edf3status Tff7b72= Te6edf3MessageStatusTb4b4b4.Te6edf3ERROR
Te6edf3assertEqualsTb4b4b4(Te6edf3storedIdTb4b4b4, Te6edf3senderTb4b4b4.Te6edf3sentPacketsTb4b4b4.Te6edf3singleTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3idTb4b4b4)
Te6edf3assertEqualsTb4b4b4(Te6edf3MessageStatusTb4b4b4.Te6edf3QUEUEDTb4b4b4, Te6edf3senderTb4b4b4.Te6edf3sentPacketsTb4b4b4.Te6edf3singleTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3statusTb4b4b4)
Te6edf3assertEqualsTb4b4b4(Ta5d6ff"Ta5d6fforiginalTa5d6ff"Tb4b4b4, Te6edf3senderTb4b4b4.Te6edf3sentPacketsTb4b4b4.Te6edf3singleTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3errorMessageTb4b4b4)
Tb4b4b4}

Tf0883e@Test
Tff7b72fun Td2a8ff`FakeCommandSender rejects data packets without a port number before assigning an id`Tb4b4b4(Tb4b4b4) Tff7b72= Te6edf3runTest Tb4b4b4{
Tff7b72val Te6edf3sender Tff7b72= Te6edf3FakeCommandSenderTb4b4b4(Tb4b4b4)
Tff7b72val Te6edf3packet Tff7b72= Te6edf3DataPacketTb4b4b4(Te6edf3bytes Tff7b72= Tff7b72nullTb4b4b4, Te6edf3dataType Tff7b72= T79c0ff0Tb4b4b4)
Tff7b72val Te6edf3nextPacketId Tff7b72= Te6edf3senderTb4b4b4.Te6edf3getCurrentPacketIdTb4b4b4(Tb4b4b4)

Te6edf3assertFailsWithTff7b72<Te6edf3IllegalArgumentExceptionTff7b72> Tb4b4b4{ Te6edf3senderTb4b4b4.Te6edf3sendDataTb4b4b4(Te6edf3packetTb4b4b4) Tb4b4b4}
Te6edf3assertEqualsTb4b4b4(T79c0ff0Tb4b4b4, Te6edf3packetTb4b4b4.Te6edf3idTb4b4b4)
Te6edf3assertEqualsTb4b4b4(Te6edf3nextPacketIdTb4b4b4, Te6edf3senderTb4b4b4.Te6edf3getCurrentPacketIdTb4b4b4(Tb4b4b4)Tb4b4b4)
Te6edf3assertTrueTb4b4b4(Te6edf3senderTb4b4b4.Te6edf3sentPacketsTb4b4b4.Te6edf3isEmptyTb4b4b4(Tb4b4b4)Tb4b4b4)
Tb4b4b4}

Tf0883e@Test
Tff7b72fun Td2a8ff`FakeCommandSender mirrors rejected data admission`Tb4b4b4(Tb4b4b4) Tff7b72= Te6edf3runTest Tb4b4b4{
Tff7b72val Te6edf3sender Tff7b72= Te6edf3FakeCommandSenderTb4b4b4(Tb4b4b4)
Tff7b72val Te6edf3rejection Tff7b72= Te6edf3PacketQueueRejectedExceptionTb4b4b4(Ta5d6ff"Ta5d6ffTest packetTa5d6ff"Tb4b4b4)
Tff7b72val Te6edf3packet Tff7b72= Te6edf3DataPacketTb4b4b4(Te6edf3bytes Tff7b72= Tff7b72nullTb4b4b4, Te6edf3dataType Tff7b72= Te6edf3PortNumTb4b4b4.Te6edf3TEXT_MESSAGE_APPTb4b4b4.Te6edf3valueTb4b4b4, Te6edf3time Tff7b72= T79c0ff1T79c0ff2T79c0ff3LTb4b4b4)
Te6edf3senderTb4b4b4.Te6edf3sendDataFailure Tff7b72= Te6edf3rejection

Tff7b72val Te6edf3failure Tff7b72= Te6edf3assertFailsWithTff7b72<Te6edf3PacketQueueRejectedExceptionTff7b72> Tb4b4b4{ Te6edf3senderTb4b4b4.Te6edf3sendDataTb4b4b4(Te6edf3packetTb4b4b4) Tb4b4b4}

Te6edf3assertSameTb4b4b4(Te6edf3rejectionTb4b4b4, Te6edf3failureTb4b4b4)
Te6edf3assertEqualsTb4b4b4(Te6edf3MessageStatusTb4b4b4.Te6edf3ERRORTb4b4b4, Te6edf3packetTb4b4b4.Te6edf3statusTb4b4b4)
Te6edf3assertEqualsTb4b4b4(T79c0ff1T79c0ff2T79c0ff3LTb4b4b4, Te6edf3packetTb4b4b4.Te6edf3timeTb4b4b4)
Te6edf3assertTrueTb4b4b4(Te6edf3senderTb4b4b4.Te6edf3sentPacketsTb4b4b4.Te6edf3isEmptyTb4b4b4(Tb4b4b4)Tb4b4b4)
Tb4b4b4}

Tf0883e@Test
Tff7b72fun Td2a8ff`FakeCommandSender records retryable admin and telemetry requests and clears them on reset`Tb4b4b4(Tb4b4b4) Tff7b72= Te6edf3runTest Tb4b4b4{
Tff7b72val Te6edf3sender Tff7b72= Te6edf3FakeCommandSenderTb4b4b4(Tb4b4b4)
Tff7b72val Te6edf3adminMessage Tff7b72= Te6edf3AdminMessageTb4b4b4(Te6edf3get_device_metadata_request Tff7b72= Tff7b72trueTb4b4b4)

Te6edf3senderTb4b4b4.Te6edf3sendAdminTb4b4b4(Te6edf3destNum Tff7b72= T79c0ff1T79c0ff2T79c0ff3Tb4b4b4, Te6edf3requestId Tff7b72= T79c0ff7Tb4b4b4, Te6edf3wantResponse Tff7b72= Tff7b72trueTb4b4b4) Tb4b4b4{ Te6edf3adminMessage Tb4b4b4}
Te6edf3senderTb4b4b4.Te6edf3requestTelemetryTb4b4b4(Te6edf3requestId Tff7b72= T79c0ff8Tb4b4b4, Te6edf3destNum Tff7b72= T79c0ff4T79c0ff5T79c0ff6Tb4b4b4, Te6edf3typeValue Tff7b72= T79c0ff2Tb4b4b4)

Te6edf3assertEqualsTb4b4b4(
Te6edf3listOfTb4b4b4(Te6edf3FakeCommandSenderTb4b4b4.Te6edf3AdminRequestTb4b4b4(T79c0ff1T79c0ff2T79c0ff3Tb4b4b4, T79c0ff7Tb4b4b4, Te6edf3wantResponse Tff7b72= Tff7b72trueTb4b4b4, Te6edf3adminMessageTb4b4b4)Tb4b4b4)Tb4b4b4,
Te6edf3senderTb4b4b4.Te6edf3adminRequestsTb4b4b4,
Tb4b4b4)
Te6edf3assertEqualsTb4b4b4(Te6edf3listOfTb4b4b4(Te6edf3FakeCommandSenderTb4b4b4.Te6edf3TelemetryRequestTb4b4b4(T79c0ff8Tb4b4b4, T79c0ff4T79c0ff5T79c0ff6Tb4b4b4, T79c0ff2Tb4b4b4)Tb4b4b4)Tb4b4b4, Te6edf3senderTb4b4b4.Te6edf3telemetryRequestsTb4b4b4)

Te6edf3senderTb4b4b4.Te6edf3resetTb4b4b4(Tb4b4b4)

Te6edf3assertTrueTb4b4b4(Te6edf3senderTb4b4b4.Te6edf3adminRequestsTb4b4b4.Te6edf3isEmptyTb4b4b4(Tb4b4b4)Tb4b4b4)
Te6edf3assertTrueTb4b4b4(Te6edf3senderTb4b4b4.Te6edf3telemetryRequestsTb4b4b4.Te6edf3isEmptyTb4b4b4(Tb4b4b4)Tb4b4b4)
Tb4b4b4}

Tf0883e@Test
Tff7b72fun Td2a8ff`FakeCommandSender accepts local-node failures on command paths`Tb4b4b4(Tb4b4b4) Tff7b72= Te6edf3runTest Tb4b4b4{
Tff7b72val Te6edf3sender Tff7b72= Te6edf3FakeCommandSenderTb4b4b4(Tb4b4b4)
Te6edf3senderTb4b4b4.Te6edf3commandFailure Tff7b72= Te6edf3LocalNodeUnavailableExceptionTb4b4b4(Ta5d6ff"Ta5d6ffTest commandTa5d6ff"Tb4b4b4)

Te6edf3assertFailsWithTff7b72<Te6edf3LocalNodeUnavailableExceptionTff7b72> Tb4b4b4{ Te6edf3senderTb4b4b4.Te6edf3requestUserInfoTb4b4b4(T79c0ff1T79c0ff2T79c0ff3Tb4b4b4) Tb4b4b4}
Tb4b4b4}

Tf0883e@Test
Tff7b72fun Td2a8ff`FakeCommandSender applies command failure before data mutation`Tb4b4b4(Tb4b4b4) Tff7b72= Te6edf3runTest Tb4b4b4{
Tff7b72val Te6edf3failure Tff7b72= Te6edf3LocalNodeUnavailableExceptionTb4b4b4(Ta5d6ff"Ta5d6ffTest commandTa5d6ff"Tb4b4b4)
Tff7b72val Te6edf3sender Tff7b72= Te6edf3FakeCommandSenderTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3apply Tb4b4b4{ Te6edf3commandFailure Tff7b72= Te6edf3failure Tb4b4b4}
Tff7b72val Te6edf3packet Tff7b72= Te6edf3DataPacketTb4b4b4(Te6edf3bytes Tff7b72= Tff7b72nullTb4b4b4, Te6edf3dataType Tff7b72= Te6edf3PortNumTb4b4b4.Te6edf3TEXT_MESSAGE_APPTb4b4b4.Te6edf3valueTb4b4b4)

Te6edf3assertSameTb4b4b4(Te6edf3failureTb4b4b4, Te6edf3assertFailsWithTff7b72<Te6edf3LocalNodeUnavailableExceptionTff7b72> Tb4b4b4{ Te6edf3senderTb4b4b4.Te6edf3sendDataTb4b4b4(Te6edf3packetTb4b4b4) Tb4b4b4}Tb4b4b4)
Te6edf3assertEqualsTb4b4b4(T79c0ff0Tb4b4b4, Te6edf3packetTb4b4b4.Te6edf3idTb4b4b4)
Te6edf3assertTrueTb4b4b4(Te6edf3senderTb4b4b4.Te6edf3sentPacketsTb4b4b4.Te6edf3isEmptyTb4b4b4(Tb4b4b4)Tb4b4b4)
Tb4b4b4}

Tf0883e@Test
Tff7b72fun Td2a8ff`FakeCommandSender applies command failure before immediate command mutation`Tb4b4b4(Tb4b4b4) Tb4b4b4{
Tff7b72val Te6edf3failure Tff7b72= Te6edf3PacketQueueRejectedExceptionTb4b4b4(Ta5d6ff"Ta5d6ffqueue closedTa5d6ff"Tb4b4b4)
Tff7b72val Te6edf3sender Tff7b72= Te6edf3FakeCommandSenderTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3apply Tb4b4b4{ Te6edf3commandFailure Tff7b72= Te6edf3failure Tb4b4b4}
Tff7b72val Te6edf3message Tff7b72= Te6edf3AdminMessageTb4b4b4(Te6edf3set_time_only Tff7b72= T79c0ff1T79c0ff2T79c0ff3Tb4b4b4)

Te6edf3assertSameTb4b4b4(Te6edf3failureTb4b4b4, Te6edf3assertFailsWithTff7b72<Te6edf3PacketQueueRejectedExceptionTff7b72> Tb4b4b4{ Te6edf3senderTb4b4b4.Te6edf3sendAdminImmediateTb4b4b4(T79c0ff7Tb4b4b4) Tb4b4b4{ Te6edf3message Tb4b4b4} Tb4b4b4}Tb4b4b4)
Te6edf3assertSameTb4b4b4(
Te6edf3failureTb4b4b4,
Te6edf3assertFailsWithTff7b72<Te6edf3PacketQueueRejectedExceptionTff7b72> Tb4b4b4{
Te6edf3senderTb4b4b4.Te6edf3sendLockdownPassphraseTb4b4b4(Ta5d6ff"Ta5d6ffsecretTa5d6ff"Tb4b4b4, Te6edf3boots Tff7b72= T79c0ff1Tb4b4b4, Te6edf3hours Tff7b72= T79c0ff2Tb4b4b4, Te6edf3maxSessionSeconds Tff7b72= T79c0ff3Tb4b4b4, Te6edf3disable Tff7b72= Tff7b72falseTb4b4b4)
Tb4b4b4}Tb4b4b4,
Tb4b4b4)
Te6edf3assertSameTb4b4b4(Te6edf3failureTb4b4b4, Te6edf3assertFailsWithTff7b72<Te6edf3PacketQueueRejectedExceptionTff7b72> Tb4b4b4{ Te6edf3senderTb4b4b4.Te6edf3sendLockNowTb4b4b4(Tb4b4b4) Tb4b4b4}Tb4b4b4)

Te6edf3assertTrueTb4b4b4(Te6edf3senderTb4b4b4.Te6edf3adminRequestsTb4b4b4.Te6edf3isEmptyTb4b4b4(Tb4b4b4)Tb4b4b4)
Te6edf3assertNullTb4b4b4(Te6edf3senderTb4b4b4.Te6edf3lastPassphraseTb4b4b4)
Te6edf3assertFalseTb4b4b4(Te6edf3senderTb4b4b4.Te6edf3lockNowCalledTb4b4b4)
Tb4b4b4}

Tf0883e@Test
Tff7b72fun Td2a8ff`FakeCommandSender records connection ownership on post-handshake requests`Tb4b4b4(Tb4b4b4) Tff7b72= Te6edf3runTest Tb4b4b4{
Tff7b72val Te6edf3sender Tff7b72= Te6edf3FakeCommandSenderTb4b4b4(Tb4b4b4)

Te6edf3senderTb4b4b4.Te6edf3sendAdminForConnectionTb4b4b4(Te6edf3destNum Tff7b72= T79c0ff1T79c0ff2T79c0ff3Tb4b4b4, Te6edf3expectedConnectionVersion Tff7b72= T79c0ff4T79c0ff1Tb4b4b4, Te6edf3requestId Tff7b72= T79c0ff7Tb4b4b4) Tb4b4b4{ Te6edf3AdminMessageTb4b4b4(Tb4b4b4) Tb4b4b4}
Te6edf3senderTb4b4b4.Te6edf3requestTelemetryForConnectionTb4b4b4(
Te6edf3requestId Tff7b72= T79c0ff8Tb4b4b4,
Te6edf3destNum Tff7b72= T79c0ff1T79c0ff2T79c0ff3Tb4b4b4,
Te6edf3typeValue Tff7b72= T79c0ff2Tb4b4b4,
Te6edf3expectedConnectionVersion Tff7b72= T79c0ff4T79c0ff1Tb4b4b4,
Tb4b4b4)

Te6edf3assertEqualsTb4b4b4(T79c0ff4T79c0ff1LTb4b4b4, Te6edf3senderTb4b4b4.Te6edf3adminRequestsTb4b4b4.Te6edf3singleTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3expectedConnectionVersionTb4b4b4)
Te6edf3assertEqualsTb4b4b4(T79c0ff4T79c0ff1LTb4b4b4, Te6edf3senderTb4b4b4.Te6edf3telemetryRequestsTb4b4b4.Te6edf3singleTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3expectedConnectionVersionTb4b4b4)
Tb4b4b4}

Tf0883e@Test
Tff7b72fun Td2a8ff`FakeRadioTransport is terminal after close`Tb4b4b4(Tb4b4b4) Tff7b72= Te6edf3runTest Tb4b4b4{
Tff7b72val Te6edf3transport Tff7b72= Te6edf3FakeRadioTransportTb4b4b4(Tb4b4b4)
Tff7b72val Te6edf3outbound Tff7b72= Te6edf3byteArrayOfTb4b4b4(T79c0ff1Tb4b4b4, T79c0ff2Tb4b4b4, T79c0ff3Tb4b4b4)

Te6edf3assertTrueTb4b4b4(Te6edf3transportTb4b4b4.Te6edf3handleSendToRadioTb4b4b4(Te6edf3outboundTb4b4b4)Tb4b4b4)
Te6edf3outboundTff7b72[T79c0ff0Tff7b72] Tff7b72= T79c0ff9
Tff7b72val Te6edf3recorded Tff7b72= Te6edf3transportTb4b4b4.Te6edf3sentDataTb4b4b4.Te6edf3singleTb4b4b4(Tb4b4b4)
Te6edf3recordedTff7b72[T79c0ff1Tff7b72] Tff7b72= T79c0ff9
Te6edf3transportTb4b4b4.Te6edf3closeTb4b4b4(Tb4b4b4)
Te6edf3transportTb4b4b4.Te6edf3clearKeepAliveTb4b4b4(Tb4b4b4)

Te6edf3assertFalseTb4b4b4(Te6edf3transportTb4b4b4.Te6edf3handleSendToRadioTb4b4b4(Te6edf3byteArrayOfTb4b4b4(T79c0ff4Tb4b4b4, T79c0ff5Tb4b4b4, T79c0ff6Tb4b4b4)Tb4b4b4)Tb4b4b4)
Te6edf3transportTb4b4b4.Te6edf3keepAliveTb4b4b4(Tb4b4b4)
Te6edf3assertFalseTb4b4b4(Te6edf3transportTb4b4b4.Te6edf3keepAliveCalledTb4b4b4)
Te6edf3assertEqualsTb4b4b4(T79c0ff1Tb4b4b4, Te6edf3transportTb4b4b4.Te6edf3sentDataTb4b4b4.Te6edf3sizeTb4b4b4)
Te6edf3assertContentEqualsTb4b4b4(Te6edf3byteArrayOfTb4b4b4(T79c0ff1Tb4b4b4, T79c0ff2Tb4b4b4, T79c0ff3Tb4b4b4)Tb4b4b4, Te6edf3transportTb4b4b4.Te6edf3sentDataTb4b4b4.Te6edf3singleTb4b4b4(Tb4b4b4)Tb4b4b4)
Tb4b4b4}

Tf0883e@Test
Tff7b72fun Td2a8ff`FakeRadioController scopes standalone hooks per write`Tb4b4b4(Tb4b4b4) Tff7b72= Te6edf3runTest Tb4b4b4{
Tff7b72val Te6edf3controller Tff7b72= Te6edf3FakeRadioControllerTb4b4b4(Tb4b4b4)
Tff7b72val Te6edf3transactionStarted Tff7b72= Te6edf3CompletableDeferredTff7b72<Tffa657UnitTff7b72>Tb4b4b4(Tb4b4b4)
Tff7b72val Te6edf3finishTransaction Tff7b72= Te6edf3CompletableDeferredTff7b72<Tffa657UnitTff7b72>Tb4b4b4(Tb4b4b4)
Tff7b72val Te6edf3standaloneHooks Tff7b72= Te6edf3mutableListOfTff7b72<Tffa657StringTff7b72>Tb4b4b4(Tb4b4b4)
Te6edf3controllerTb4b4b4.Te6edf3onStandaloneConfig Tff7b72= Tb4b4b4{ Te6edf3standaloneHooks Tff7b72+Tff7b72= Ta5d6ff"Ta5d6ffconfigTa5d6ff" Tb4b4b4}
Te6edf3controllerTb4b4b4.Te6edf3onStandaloneModuleConfig Tff7b72= Tb4b4b4{ Te6edf3standaloneHooks Tff7b72+Tff7b72= Ta5d6ff"Ta5d6ffmoduleTa5d6ff" Tb4b4b4}

Tff7b72val Te6edf3transaction Tff7b72= Te6edf3async Tb4b4b4{
Te6edf3controllerTb4b4b4.Te6edf3editSettingsTb4b4b4(Te6edf3destNum Tff7b72= T79c0ff7Tb4b4b4) Tb4b4b4{
Te6edf3transactionStartedTb4b4b4.Te6edf3completeTb4b4b4(Tffa657UnitTb4b4b4)
Te6edf3finishTransactionTb4b4b4.Te6edf3awaitTb4b4b4(Tb4b4b4)
Te6edf3setConfigTb4b4b4(Te6edf3ConfigTb4b4b4(Te6edf3device Tff7b72= Te6edf3ConfigTb4b4b4.Te6edf3DeviceConfigTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4)
Te6edf3setModuleConfigTb4b4b4(Te6edf3ModuleConfigTb4b4b4(Te6edf3serial Tff7b72= Te6edf3ModuleConfigTb4b4b4.Te6edf3SerialConfigTb4b4b4(Te6edf3enabled Tff7b72= Tff7b72trueTb4b4b4)Tb4b4b4)Tb4b4b4)
Tb4b4b4}
Tb4b4b4}
Te6edf3transactionStartedTb4b4b4.Te6edf3awaitTb4b4b4(Tb4b4b4)

Te6edf3controllerTb4b4b4.Te6edf3setConfigTb4b4b4(Te6edf3destNum Tff7b72= T79c0ff8Tb4b4b4, Te6edf3config Tff7b72= Te6edf3ConfigTb4b4b4(Te6edf3power Tff7b72= Te6edf3ConfigTb4b4b4.Te6edf3PowerConfigTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4, Te6edf3packetId Tff7b72= T79c0ff1Tb4b4b4)
Te6edf3controllerTb4b4b4.Te6edf3setModuleConfigTb4b4b4(
Te6edf3destNum Tff7b72= T79c0ff8Tb4b4b4,
Te6edf3config Tff7b72= Te6edf3ModuleConfigTb4b4b4(Te6edf3mqtt Tff7b72= Te6edf3ModuleConfigTb4b4b4.Te6edf3MQTTConfigTb4b4b4(Te6edf3enabled Tff7b72= Tff7b72trueTb4b4b4)Tb4b4b4)Tb4b4b4,
Te6edf3packetId Tff7b72= T79c0ff2Tb4b4b4,
Tb4b4b4)
Te6edf3finishTransactionTb4b4b4.Te6edf3completeTb4b4b4(Tffa657UnitTb4b4b4)
Te6edf3transactionTb4b4b4.Te6edf3awaitTb4b4b4(Tb4b4b4)

Te6edf3assertEqualsTb4b4b4(Te6edf3listOfTb4b4b4(Ta5d6ff"Ta5d6ffconfigTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffmoduleTa5d6ff"Tb4b4b4)Tb4b4b4, Te6edf3standaloneHooksTb4b4b4)
Te6edf3assertEqualsTb4b4b4(
Te6edf3listOfTb4b4b4(
Te6edf3FakeRadioControllerTb4b4b4.Te6edf3ConfigWriteTb4b4b4(Te6edf3destination Tff7b72= T79c0ff8Tb4b4b4, Te6edf3config Tff7b72= Te6edf3ConfigTb4b4b4(Te6edf3power Tff7b72= Te6edf3ConfigTb4b4b4.Te6edf3PowerConfigTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4)Tb4b4b4,
Te6edf3FakeRadioControllerTb4b4b4.Te6edf3ConfigWriteTb4b4b4(Te6edf3destination Tff7b72= T79c0ff7Tb4b4b4, Te6edf3config Tff7b72= Te6edf3ConfigTb4b4b4(Te6edf3device Tff7b72= Te6edf3ConfigTb4b4b4.Te6edf3DeviceConfigTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4)Tb4b4b4,
Tb4b4b4)Tb4b4b4,
Te6edf3controllerTb4b4b4.Te6edf3configWritesTb4b4b4,
Tb4b4b4)
Te6edf3assertEqualsTb4b4b4(
Te6edf3listOfTb4b4b4(
Te6edf3FakeRadioControllerTb4b4b4.Te6edf3ModuleConfigWriteTb4b4b4(
Te6edf3destination Tff7b72= T79c0ff8Tb4b4b4,
Te6edf3config Tff7b72= Te6edf3ModuleConfigTb4b4b4(Te6edf3mqtt Tff7b72= Te6edf3ModuleConfigTb4b4b4.Te6edf3MQTTConfigTb4b4b4(Te6edf3enabled Tff7b72= Tff7b72trueTb4b4b4)Tb4b4b4)Tb4b4b4,
Tb4b4b4)Tb4b4b4,
Te6edf3FakeRadioControllerTb4b4b4.Te6edf3ModuleConfigWriteTb4b4b4(
Te6edf3destination Tff7b72= T79c0ff7Tb4b4b4,
Te6edf3config Tff7b72= Te6edf3ModuleConfigTb4b4b4(Te6edf3serial Tff7b72= Te6edf3ModuleConfigTb4b4b4.Te6edf3SerialConfigTb4b4b4(Te6edf3enabled Tff7b72= Tff7b72trueTb4b4b4)Tb4b4b4)Tb4b4b4,
Tb4b4b4)Tb4b4b4,
Tb4b4b4)Tb4b4b4,
Te6edf3controllerTb4b4b4.Te6edf3moduleConfigWritesTb4b4b4,
Tb4b4b4)
Te6edf3assertEqualsTb4b4b4(
Te6edf3listOfTb4b4b4(Ta5d6ff"Ta5d6ffbeginTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffconfig:updateTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffmodule:updateTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffconfig:updateTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffmodule:updateTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffcommitTa5d6ff"Tb4b4b4)Tb4b4b4,
Te6edf3controllerTb4b4b4.Te6edf3adminOperationsTb4b4b4,
Tb4b4b4)
Tb4b4b4}

Tf0883e@Test
Tff7b72fun Td2a8ff`FakeRadioController records owner destinations consistently`Tb4b4b4(Tb4b4b4) Tff7b72= Te6edf3runTest Tb4b4b4{
Tff7b72val Te6edf3controller Tff7b72= Te6edf3FakeRadioControllerTb4b4b4(Tb4b4b4)
Tff7b72val Te6edf3localOwner Tff7b72= Te6edf3UserTb4b4b4(Te6edf3id Tff7b72= Ta5d6ff"Ta5d6ff!00000001Ta5d6ff"Tb4b4b4, Te6edf3long_name Tff7b72= Ta5d6ff"Ta5d6ffLocalTa5d6ff"Tb4b4b4)
Tff7b72val Te6edf3remoteOwner Tff7b72= Te6edf3UserTb4b4b4(Te6edf3id Tff7b72= Ta5d6ff"Ta5d6ff!00000002Ta5d6ff"Tb4b4b4, Te6edf3long_name Tff7b72= Ta5d6ff"Ta5d6ffRemoteTa5d6ff"Tb4b4b4)

Te6edf3controllerTb4b4b4.Te6edf3setOwnerTb4b4b4(Te6edf3destNum Tff7b72= T79c0ff0Tb4b4b4, Te6edf3user Tff7b72= Te6edf3localOwnerTb4b4b4, Te6edf3packetId Tff7b72= T79c0ff1Tb4b4b4)
Te6edf3controllerTb4b4b4.Te6edf3setOwnerTb4b4b4(Te6edf3destNum Tff7b72= T79c0ff7Tb4b4b4, Te6edf3user Tff7b72= Te6edf3remoteOwnerTb4b4b4, Te6edf3packetId Tff7b72= T79c0ff2Tb4b4b4)

Te6edf3assertEqualsTb4b4b4(
Te6edf3listOfTb4b4b4(
Te6edf3FakeRadioControllerTb4b4b4.Te6edf3OwnerWriteTb4b4b4(Te6edf3destination Tff7b72= Tff7b72nullTb4b4b4, Te6edf3user Tff7b72= Te6edf3localOwnerTb4b4b4)Tb4b4b4,
Te6edf3FakeRadioControllerTb4b4b4.Te6edf3OwnerWriteTb4b4b4(Te6edf3destination Tff7b72= T79c0ff7Tb4b4b4, Te6edf3user Tff7b72= Te6edf3remoteOwnerTb4b4b4)Tb4b4b4,
Tb4b4b4)Tb4b4b4,
Te6edf3controllerTb4b4b4.Te6edf3ownerWritesTb4b4b4,
Tb4b4b4)

Te6edf3controllerTb4b4b4.Te6edf3resetTb4b4b4(Tb4b4b4)
Te6edf3assertTrueTb4b4b4(Te6edf3controllerTb4b4b4.Te6edf3ownerWritesTb4b4b4.Te6edf3isEmptyTb4b4b4(Tb4b4b4)Tb4b4b4)
Tb4b4b4}

Tf0883e@Test
Tff7b72fun Td2a8ff`FakeRadioController rejects edit settings before running writes when begin fails`Tb4b4b4(Tb4b4b4) Tff7b72= Te6edf3runTest Tb4b4b4{
Tff7b72val Te6edf3controller Tff7b72= Te6edf3FakeRadioControllerTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3apply Tb4b4b4{ Te6edf3failEditSettingsBegin Tff7b72= Tff7b72true Tb4b4b4}
Tff7b72var Te6edf3blockRan Tff7b72= Tff7b72false

Te6edf3assertFailsWithTff7b72<Te6edf3EditSettingsTransactionExceptionTff7b72> Tb4b4b4{ Te6edf3controllerTb4b4b4.Te6edf3editLocalSettings Tb4b4b4{ Te6edf3blockRan Tff7b72= Tff7b72true Tb4b4b4} Tb4b4b4}

Te6edf3assertFalseTb4b4b4(Te6edf3blockRanTb4b4b4)
Te6edf3assertTrueTb4b4b4(Te6edf3controllerTb4b4b4.Te6edf3editSettingsCalledTb4b4b4)
Te6edf3assertEqualsTb4b4b4(Te6edf3listOfTb4b4b4(T79c0ff0Tb4b4b4)Tb4b4b4, Te6edf3controllerTb4b4b4.Te6edf3editSettingsDestinationsTb4b4b4)
Te6edf3assertTrueTb4b4b4(Te6edf3controllerTb4b4b4.Te6edf3adminOperationsTb4b4b4.Te6edf3isEmptyTb4b4b4(Tb4b4b4)Tb4b4b4)
Tb4b4b4}

Tf0883e@Test
Tff7b72fun Td2a8ff`FakeRadioController reset clears begin-boundary failure hook`Tb4b4b4(Tb4b4b4) Tb4b4b4{
Tff7b72val Te6edf3controller Tff7b72= Te6edf3FakeRadioControllerTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3apply Tb4b4b4{ Te6edf3failEditSettingsBegin Tff7b72= Tff7b72true Tb4b4b4}

Te6edf3controllerTb4b4b4.Te6edf3resetTb4b4b4(Tb4b4b4)

Te6edf3assertFalseTb4b4b4(Te6edf3controllerTb4b4b4.Te6edf3failEditSettingsBeginTb4b4b4)
Tb4b4b4}

Tf0883e@Test
Tff7b72fun Td2a8ff`FakeRadioController commits after block failure and preserves failure precedence`Tb4b4b4(Tb4b4b4) Tff7b72= Te6edf3runTest Tb4b4b4{
Tff7b72val Te6edf3controller Tff7b72= Te6edf3FakeRadioControllerTb4b4b4(Tb4b4b4)
Tff7b72val Te6edf3blockFailure Tff7b72= Te6edf3IllegalStateExceptionTb4b4b4(Ta5d6ff"Ta5d6ffwrite failedTa5d6ff"Tb4b4b4)
Tff7b72val Te6edf3commitFailure Tff7b72= Te6edf3IllegalArgumentExceptionTb4b4b4(Ta5d6ff"Ta5d6ffcommit failedTa5d6ff"Tb4b4b4)
Te6edf3controllerTb4b4b4.Te6edf3onEditSettingsCommitted Tff7b72= Tb4b4b4{ Tff7b72throw Te6edf3commitFailure Tb4b4b4}

Tff7b72val Te6edf3failure Tff7b72= Te6edf3assertFailsWithTff7b72<Te6edf3IllegalStateExceptionTff7b72> Tb4b4b4{ Te6edf3controllerTb4b4b4.Te6edf3editLocalSettings Tb4b4b4{ Tff7b72throw Te6edf3blockFailure Tb4b4b4} Tb4b4b4}

Te6edf3assertSameTb4b4b4(Te6edf3blockFailureTb4b4b4, Te6edf3failureTb4b4b4)
Te6edf3assertEqualsTb4b4b4(Te6edf3listOfTb4b4b4(Te6edf3commitFailureTb4b4b4.Te6edf3messageTb4b4b4)Tb4b4b4, Te6edf3failureTb4b4b4.Te6edf3suppressedExceptionsTb4b4b4.Te6edf3mapTb4b4b4(Te6edf3ThrowableTff7b72::Te6edf3messageTb4b4b4)Tb4b4b4)
Te6edf3assertIsTff7b72<Te6edf3IllegalArgumentExceptionTff7b72>Tb4b4b4(Te6edf3failureTb4b4b4.Te6edf3suppressedExceptionsTb4b4b4.Te6edf3singleTb4b4b4(Tb4b4b4)Tb4b4b4)
Te6edf3assertEqualsTb4b4b4(Te6edf3listOfTb4b4b4(Ta5d6ff"Ta5d6ffbeginTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffcommitTa5d6ff"Tb4b4b4)Tb4b4b4, Te6edf3controllerTb4b4b4.Te6edf3adminOperationsTb4b4b4)
Tb4b4b4}

Tf0883e@Test
Tff7b72fun Td2a8ff`FakeRadioController preserves a distinct same-looking commit failure`Tb4b4b4(Tb4b4b4) Tff7b72= Te6edf3runTest Tb4b4b4{
Tff7b72val Te6edf3controller Tff7b72= Te6edf3FakeRadioControllerTb4b4b4(Tb4b4b4)
Tff7b72val Te6edf3blockFailure Tff7b72= Te6edf3IllegalStateExceptionTb4b4b4(Ta5d6ff"Ta5d6ffsame recovered failureTa5d6ff"Tb4b4b4)
Te6edf3controllerTb4b4b4.Te6edf3onEditSettingsCommitted Tff7b72= Tb4b4b4{ Tff7b72throw Te6edf3IllegalStateExceptionTb4b4b4(Ta5d6ff"Ta5d6ffsame recovered failureTa5d6ff"Tb4b4b4) Tb4b4b4}

Tff7b72val Te6edf3failure Tff7b72= Te6edf3assertFailsWithTff7b72<Te6edf3IllegalStateExceptionTff7b72> Tb4b4b4{ Te6edf3controllerTb4b4b4.Te6edf3editLocalSettings Tb4b4b4{ Tff7b72throw Te6edf3blockFailure Tb4b4b4} Tb4b4b4}

Te6edf3assertSameTb4b4b4(Te6edf3blockFailureTb4b4b4, Te6edf3failureTb4b4b4)
Te6edf3assertEqualsTb4b4b4(T79c0ff1Tb4b4b4, Te6edf3failureTb4b4b4.Te6edf3suppressedExceptionsTb4b4b4.Te6edf3sizeTb4b4b4)
Te6edf3assertNotSameTb4b4b4(Te6edf3blockFailureTb4b4b4, Te6edf3failureTb4b4b4.Te6edf3suppressedExceptionsTb4b4b4.Te6edf3singleTb4b4b4(Tb4b4b4)Tb4b4b4)
Te6edf3assertEqualsTb4b4b4(Te6edf3blockFailureTb4b4b4.Te6edf3messageTb4b4b4, Te6edf3failureTb4b4b4.Te6edf3suppressedExceptionsTb4b4b4.Te6edf3singleTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3messageTb4b4b4)
Tb4b4b4}

Tf0883e@Test
Tff7b72fun Td2a8ff`FakeRadioController does not suppress a recovered copy of the block failure`Tb4b4b4(Tb4b4b4) Tff7b72= Te6edf3runTest Tb4b4b4{
Tff7b72val Te6edf3controller Tff7b72= Te6edf3FakeRadioControllerTb4b4b4(Tb4b4b4)
Tff7b72val Te6edf3blockFailure Tff7b72= Te6edf3IllegalStateExceptionTb4b4b4(Ta5d6ff"Ta5d6ffsame recovered failureTa5d6ff"Tb4b4b4)
Te6edf3controllerTb4b4b4.Te6edf3onEditSettingsCommitted Tff7b72= Tb4b4b4{ Tff7b72throw Te6edf3blockFailure Tb4b4b4}

Tff7b72val Te6edf3failure Tff7b72= Te6edf3assertFailsWithTff7b72<Te6edf3IllegalStateExceptionTff7b72> Tb4b4b4{ Te6edf3controllerTb4b4b4.Te6edf3editLocalSettings Tb4b4b4{ Tff7b72throw Te6edf3blockFailure Tb4b4b4} Tb4b4b4}

Te6edf3assertSameTb4b4b4(Te6edf3blockFailureTb4b4b4, Te6edf3failureTb4b4b4)
Te6edf3assertTrueTb4b4b4(Te6edf3failureTb4b4b4.Te6edf3suppressedExceptionsTb4b4b4.Te6edf3isEmptyTb4b4b4(Tb4b4b4)Tb4b4b4)
Tb4b4b4}

Tf0883e@Test
Tff7b72fun Td2a8ff`FakeRadioConfigRepository tracks channel set and module config`Tb4b4b4(Tb4b4b4) Tff7b72= Te6edf3runTest Tb4b4b4{
Tff7b72val Te6edf3repo Tff7b72= Te6edf3FakeRadioConfigRepositoryTb4b4b4(Tb4b4b4)
Tff7b72val Te6edf3a Tff7b72= Te6edf3ChannelSettingsTb4b4b4(Te6edf3name Tff7b72= Ta5d6ff"Ta5d6ffATa5d6ff"Tb4b4b4)
Tff7b72val Te6edf3b Tff7b72= Te6edf3ChannelSettingsTb4b4b4(Te6edf3name Tff7b72= Ta5d6ff"Ta5d6ffBTa5d6ff"Tb4b4b4)

Te6edf3repoTb4b4b4.Te6edf3replaceAllSettingsTb4b4b4(Te6edf3listOfTb4b4b4(Te6edf3aTb4b4b4, Te6edf3bTb4b4b4)Tb4b4b4)
Te6edf3assertEqualsTb4b4b4(Te6edf3listOfTb4b4b4(Te6edf3aTb4b4b4, Te6edf3bTb4b4b4)Tb4b4b4, Te6edf3repoTb4b4b4.Te6edf3currentChannelSetTb4b4b4.Te6edf3settingsTb4b4b4)

Te6edf3repoTb4b4b4.Te6edf3updateChannelSettingsTb4b4b4(Te6edf3ChannelTb4b4b4(Te6edf3index Tff7b72= T79c0ff1Tb4b4b4, Te6edf3settings Tff7b72= Te6edf3ChannelSettingsTb4b4b4(Te6edf3name Tff7b72= Ta5d6ff"Ta5d6ffB2Ta5d6ff"Tb4b4b4)Tb4b4b4)Tb4b4b4)
Te6edf3assertEqualsTb4b4b4(Ta5d6ff"Ta5d6ffB2Ta5d6ff"Tb4b4b4, Te6edf3repoTb4b4b4.Te6edf3currentChannelSetTb4b4b4.Te6edf3settingsTff7b72[T79c0ff1Tff7b72]Tb4b4b4.Te6edf3nameTb4b4b4)

Te6edf3repoTb4b4b4.Te6edf3clearChannelSetTb4b4b4(Tb4b4b4)
Te6edf3assertTrueTb4b4b4(Te6edf3repoTb4b4b4.Te6edf3currentChannelSetTb4b4b4.Te6edf3settingsTb4b4b4.Te6edf3isEmptyTb4b4b4(Tb4b4b4)Tb4b4b4)
Tb4b4b4}
Tb4b4b4}

Served by rngit 1.5.0 - Generated in 0.16s